package com.gupao.proxy;

/**
 * @Description: //TODO:
 * @ClassName: ProxyLoggerFactoryTest
 * @Author: msx
 * @CreateDate: 2018/3/23 18:57
 */
public class ProxyLoggerFactoryTest {

    public static void main(String[] args) {

        //动态获取该类.
        //比如我在业务中只管，一直往一个map中放入logger对象和方法，至于他调用什么，我不管，
        // 在真实的业务中：
        //              可以把多个日志类实现该接口，该接口只有一个实现方法，每次调用走不同的方法，而不是现在的三个方法
        //              这样看起来更清晰明了，就像下面的userActionLogger
        //new JDKProxyLoggerFactory().executeLogger(new LoggerFactory())生成一个$proxy0的对象
        ILoggerFactory factory = (ILoggerFactory)new JDKProxyLoggerFactory().executeLogger(new LoggerFactory());
       //调用
        factory.userActionLogger(new Logger());

        //
        factory = (ILoggerFactory)new JDKProxyLoggerFactory().executeLogger(new LoggerFactory());
        factory.userActionLogger(new Logger());


        /**
         * 老师说的话，拿过来
         */
        //原理：
        //1、拿到被代理对象的引用，并且获取到它的所有的接口，反射获取
        //2、JDK Proxy类重新生成一个新的类、同时新的类要实现被代理类所有实现的所有的接口
        //3、动态生成Java代码，把新加的业务逻辑方法由一定的逻辑代码去调用（在代码中体现）
        //4、编译新生成的Java代码.class
        //5、再重新加载到JVM中运行
        //以上这个过程就叫字节码重组

        //JDK中有个规范，只要要是$开头的一般都是自动生成的

        //通过反编译工具可以查看源代码
       /* byte [] bytes = ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{Person.class});
        FileOutputStream os = new FileOutputStream("E://$Proxy0.class");
        os.write(bytes);
        os.close();*/
    }
}
